<template>
  <div class="content-container">
    <div class="top-upload">
      <el-upload
        class="upload-demo"
        :http-request="customUpload"
        :before-upload="beforeUpload"
        :file-list="fileList"
        :on-remove="handleRemove"
        drag
        multiple
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖拽到此处或 <em>点击上传</em></div>
        <div class="el-upload__tip">文件大小不超过 5MB。</div>
      </el-upload>
    </div>
    <div class="card-search">
      <el-input
        v-model="inputSearch"
        placeholder="请输入块文本"
        :suffix-icon="Search"
        @input="handleInput"
        @clear="handleClear"
        clearable
      />
    </div>
    <div class="kb-content">
      <el-row :gutter="20">
        <el-col v-for="(card, index) in blockList" :key="index" :span="8">
          <el-card class="card">
            <div class="card-title">{{ card.id || "" }}</div>
            <div class="card-content">
              {{ card.text || card.metadata?.text }}
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script setup lang="ts">
import { onMounted, ref, watch } from "vue";
import { useRoute } from "vue-router";
import axios, { CancelTokenSource } from "axios";
import { ElMessage, UploadProps, UploadUserFile } from "element-plus";
import { UploadFilled, Search } from "@element-plus/icons-vue";
import { KnowledgeApi } from "@/api/api";
import debounce from "lodash/debounce";
// 文件列表
const fileList = ref<UploadUserFile[]>([]);
// 当前的取消令牌源
const cancelTokenSource = ref<CancelTokenSource | null>(null);
// 搜索框
const inputSearch = ref("");
const route = useRoute();
// 路由参数id
const knowledgeId = ref(0);
// 文本块列表
const blockList = ref([]);
// 上传前的校验
const beforeUpload: UploadProps["beforeUpload"] = (file) => {
  const isAllowedType =
    file.type === "application/pdf" ||
    file.type === "image/jpeg" ||
    file.type === "image/png";
  const isLt5M = file.size / 1024 / 1024 < 5;

  if (isAllowedType) {
    ElMessage.error("不能上传 PDF、JPEG、PNG 格式的文件！");
    return false;
  }
  if (!isLt5M) {
    ElMessage.error("上传文件大小不能超过 5MB！");
    return false;
  }
  return true;
};
// 搜索处理函数
const handleSearch = async (query: string) => {
  if (!query.trim()) return;

  // 取消之前的请求
  if (cancelTokenSource.value) {
    cancelTokenSource.value.cancel("Search canceled due to new request.");
  }
  cancelTokenSource.value = axios.CancelToken.source();

  try {
    const { data } = await KnowledgeApi.SearchKbBlocks(
      { kb_id: knowledgeId.value, query },
      { cancelToken: cancelTokenSource.value.token }
    );
    blockList.value = data.results || [];
    // 错误处理和空状态提示...
  } catch (error) {
    if (!axios.isCancel(error)) {
      console.error("搜索失败", error);
      ElMessage.error("搜索失败，请稍后再试！");
    }
  }
};

//  防抖处理：用户停止输入 300ms 后自动搜索
const debouncedSearch = debounce(handleSearch, 300);

//  输入处理（包括清空）
const handleInput = () => {
  if (!inputSearch.value.trim()) {
    getAllBlocks(); // 输入为空时立即加载全部数据
  } else {
    debouncedSearch(inputSearch.value); // 非空时防抖搜索
  }
};
//  清空搜索框时，重新加载全部数据
const handleClear = () => {
  inputSearch.value = "";
  getAllBlocks();
};
// 自定义上传方法
const customUpload: UploadProps["httpRequest"] = async (options) => {
  console.log("开始上传文件", options.file);

  const { file, onSuccess, onError, onProgress } = options;
  const formData = new FormData();
  formData.append("file", file);
  formData.append("kb_id", knowledgeId.value.toString());

  try {
    const response = await axios.post("/api/upload", formData, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
      onUploadProgress: (progressEvent) => {
        const percentCompleted = Math.round(
          (progressEvent.loaded * 100) / progressEvent.total
        );
        console.log(`上传进度: ${percentCompleted}%`);
        onProgress && onProgress({ percent: percentCompleted });
      },
    });

    console.log("上传成功", response.data);
    ElMessage.success(`文件 "${file.name}" 上传成功！`);
    getAllBlocks();
    // 更新文件列表，确保前端展示
    fileList.value.push({
      name: file.name,
      url: response.data.fileUrl || "", // 假设后端返回 fileUrl
    });
    onSuccess && onSuccess(response.data);
  } catch (error) {
    console.error("上传失败", error); //
    ElMessage.error(`文件 "${file.name}" 上传失败！`);
    onError && onError(error);
  }
};

// 删除文件的回调
const handleRemove: UploadProps["onRemove"] = (file) => {
  fileList.value = fileList.value.filter((item) => item.name !== file.name);
  ElMessage.info(`已删除文件：${file.name}`);
};
// 获取文件块列表
const getAllBlocks = async () => {
  // 取消之前的请求
  if (cancelTokenSource.value) {
    cancelTokenSource.value.cancel('Fetch canceled due to new request.');
  }
  cancelTokenSource.value = axios.CancelToken.source();

  try {
    const { data } = await KnowledgeApi.getFileBlocks(
      knowledgeId.value,
      { cancelToken: cancelTokenSource.value.token }
    );
    blockList.value = data.texts;
  } catch (error) {
    if (!axios.isCancel(error)) {
      console.error("获取数据失败", error);
      ElMessage.error("获取数据失败！");
    }
  }
};
onMounted(() => {
  getAllBlocks();
});
// 监听路由变化
watch(
  () => route.params.id,
  (newId) => {
    knowledgeId.value = Number(newId);
    if (knowledgeId.value) {
      // loadKnowledgeData(knowledgeId.value);
      getAllBlocks();
    }
  },
  { immediate: true } // 立即执行确保首次加载有效
);
</script>
<style lang="less" scoped>
.content-container {
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  .top-upload {
    width: 100%;
    height: 25%;
    display: flex;
    align-items: center;
    justify-content: center;
    margin-bottom: 1%;
    .upload-demo {
      width: 100%;
      height: 100%;
    }
    .top-upload:hover {
      background-color: #f0f9eb;
      border-color: #67c23a;
    }

    .el-upload__text em {
      color: #409eff;
      font-style: normal;
      cursor: pointer;
    }
  }
  .card-search {
    margin-left: auto;
    margin-bottom: 0.2%;
    margin-right: 1%;
    width: 20%;
  }
  .kb-content {
    width: 100%;
    height: 74%;
    overflow-y: auto;
    scrollbar-width: none; /* Firefox */
    -ms-overflow-style: none; /* IE/Edge */
    &::-webkit-scrollbar {
      display: none; /* Chrome/Safari */
    }
    .card {
      background-color: #f9fafb;
      border-radius: 3%;
      height: 260px;
      margin-bottom: 2%;
      .card-title {
        display: inline-block;
        border: 0.5px solid rgb(234, 236, 240);
        border-radius: 8px;
        padding: 4px;
        font-size: 11px;
        font-weight: 500;
        color: rgb(102 112 133);
      }
      .card-content {
        /* 布局核心 */
        height: 180px;
        max-height: 180px;
        overflow-y: auto;

        /* 内容样式 */
        white-space: pre-wrap;
        font-family: monospace;
        padding: 10px;
        margin-top: 0.5rem;
        flex: 1 1 0%;
        font-size: 0.9rem;
        line-height: 1.25rem;
        font-family: Source Han Sans;
        font-weight: 400;

        /* 滚动条控制 */
        scrollbar-width: none; /* Firefox */
        -ms-overflow-style: none; /* IE/Edge */
        &::-webkit-scrollbar {
          display: none; /* Chrome/Safari */
        }
      }
      .card-content::-webkit-scrollbar {
        display: none; /* Chrome、Safari 隐藏滚动条 */
      }
    }
  }
}
</style>
